#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>

#include "global.h"
#include "constantes.h"
#include "sockets.h"
#include "NIPC.h"


int generarStructIPC(char *payload, short mode, InfoIPC* rInfoIPC)  /*short es 2 bytes,int es 4 bytes,uso short porq no es necesario usar mas en este caso*/
{	
	
	strcpy(rInfoIPC->descriptorID,GenerarDescriptor()); /*creo el descriptor y lo cargo en la estructura. */
	rInfoIPC->payLoadDescriptor=mode; /*cargo el protocolo a la struct*/
	/*rInfoIPC->payLoadLength = strlen(payload) +1;*/
	rInfoIPC->payload = (char*) malloc(rInfoIPC->payLoadLength);
	memset(rInfoIPC->payload,'\0',rInfoIPC->payLoadLength);
	memcpy(rInfoIPC->payload, payload,rInfoIPC->payLoadLength); 
	

	return 0; 
}


char* GenerarDescriptor(){

	static char descriptor[16];
	char cadena [] = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	int pos = 0;

 
	memset(descriptor, '\0', 16);

	for(pos = 0; pos < 15; descriptor[pos++] = cadena[(int)(rand()%62)]);
	descriptor[pos] = '\0';

	return descriptor;
}


int enviarIPC(int sock, InfoIPC *rInfoIPC)
{
	int tm;
	char *buffer;
	int bufLen;
	int length;

	bufLen = (sizeof(char) * strlen(rInfoIPC->descriptorID)) + sizeof(short) + sizeof(long) + sizeof(char)*rInfoIPC->payLoadLength + 20; /*Ese 20 no se de donde sale pero por las dudas lo dejo*/

   buffer	= (char*)malloc(bufLen);
   length =0;
   memcpy (buffer,&(rInfoIPC->payLoadLength),sizeof(long));
   length = sizeof(long);
   memcpy(buffer + length, &(rInfoIPC->payLoadDescriptor), sizeof(short));
   length += sizeof(short);
   memcpy(buffer + length, rInfoIPC->descriptorID, strlen(rInfoIPC->descriptorID)+1);
   length += strlen(rInfoIPC->descriptorID)+1;
   memcpy(buffer + length, rInfoIPC->payload, rInfoIPC->payLoadLength);
   length +=  rInfoIPC->payLoadLength; 

	tm = send(sock,buffer,length,MSG_WAITALL);
	
	free(buffer);
	return tm;
}


/*
int recibirIPC(int sock, InfoIPC* rInfoIPC)
{
	int length;
	int len;
	char* buffer;
	char* payload;
	int ret;

   
	len = sizeof(short) + sizeof(long) + 16; 
	buffer	= (char*) malloc(len);
	ret = recv(sock, buffer, len, 0);
	rInfoIPC->payLoadLength = 0;
	if(ret == len)
	{   
		length  = 0;
		rInfoIPC->payLoadLength =  *((long *) buffer);
		length += sizeof(long);

		rInfoIPC->payLoadDescriptor = *((short*) (buffer + length));
		length += sizeof(short);

		strncpy(rInfoIPC->descriptorID,(char*)( buffer + length),16);
		length += 16;
	}else return -1; 
	
	if(rInfoIPC->payLoadLength > 0)
	{

      payload	= (char*)malloc(rInfoIPC->payLoadLength);
      ret = recv(sock, payload,  rInfoIPC->payLoadLength, 0);  
      rInfoIPC->payload 	= (char*)malloc(rInfoIPC->payLoadLength);
   	
      memset(rInfoIPC->payload,'\0',rInfoIPC->payLoadLength);
		memcpy(rInfoIPC->payload,payload,rInfoIPC->payLoadLength);
		return 0; 

   }else 
      return HANDSHAKE;	
   
}	

*/






int recibirIPC(int sock, InfoIPC* rInfoIPC)
{
	int length;
	int len;
	char* buffer;
	char* payload;
	int ret;
	int bRecibidos = 0;
	int bHastaAhora = 0;

	len = sizeof(short) + sizeof(long) + 16; 

	buffer	= (char*) malloc(len);

	ret = recv(sock, buffer, len, MSG_WAITALL);
	rInfoIPC->payLoadLength = 0;
	if(ret == len)
	{   
		length  = 0;
		rInfoIPC->payLoadLength =  *((long *) buffer);
		length += sizeof(long);

		rInfoIPC->payLoadDescriptor = *((short*) (buffer + length));
		length += sizeof(short);

		strncpy(rInfoIPC->descriptorID,(char*)( buffer + length),16);
		length += 16;
		
		free(buffer);
	}else return -1; 
	
	
	if(rInfoIPC->payLoadLength > 0)
	{
		payload = (char *) malloc(rInfoIPC->payLoadLength);
			
		do
		{
			if ((bHastaAhora = recv(sock, payload, rInfoIPC->payLoadLength, MSG_WAITALL)) == -1)
			{
				return -1;
			}
			if (bHastaAhora == 0)
			{
				return 0;
			}

			bRecibidos += bHastaAhora;

		}while (bRecibidos != (rInfoIPC->payLoadLength));
		
		if (bRecibidos < (rInfoIPC->payLoadLength)) {
			printf("Error al recibir datos (datos recibidos %i)\n",rInfoIPC->payLoadLength);
			return ERROR;
		}
		
		rInfoIPC->payload = (char*)malloc(rInfoIPC->payLoadLength);
		memcpy(rInfoIPC->payload,payload,rInfoIPC->payLoadLength);
		free(payload);
		return 0; 
	
   }else return HANDSHAKE;	
}	



int recibirIPC_Sector(int sock, InfoIPC* rInfoIPC)
{
	int length;
	int len;
	char* buffer;
	char* payload;
	int ret;

   
	len = sizeof(short) + sizeof(long) + 16 +512; 
	buffer	= (char*) malloc(len);
	ret = recv(sock, buffer, len, 0);
	rInfoIPC->payLoadLength = 0;
	
		length  = 0;
		rInfoIPC->payLoadLength =  *((long *) buffer);
		length += sizeof(long);

		rInfoIPC->payLoadDescriptor = *((short*) (buffer + length));
		length += sizeof(short);

		strncpy(rInfoIPC->descriptorID,(char*)( buffer + length),16);
		length += 16;
		
        rInfoIPC->payload = (char*)malloc(512);
	
        memset(rInfoIPC->payload,'\0',512);  
		memcpy(rInfoIPC->payload,buffer+sizeof(short) + sizeof(long) + 16,512);
		return 0; 
		
   
}	


















